package com.ycz.sas.jgen.handler;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.List;

import com.ycz.sas.jgen.util.MD5Util;

public class ScanNew {

	private String SOURCEPATH;
	private String COMPAREPATH;
	private String TARGETPATH;
	private String cfgPath;

	private FileLock cfgLock;

	private boolean isIgnoreUpdate;

	private List<String> filter = new ArrayList<String>();
	private List<String> negaFilter = new ArrayList<String>();

	public static void main(String[] args) {
		ScanNew sn=new ScanNew();;
		System.out.println("======"+args[0]);
		System.out.println("======"+args[1]);
		System.out.println("======"+args[2]);
		sn.setSOURCEPATH(args[0]);
		sn.setCOMPAREPATH(args[1]);
		sn.setTARGETPATH(args[2]);
		sn.setCfgPath(args[3]);
		System.out.println("扫描对比文件中.....\n");
		long starttime=System.currentTimeMillis();
		sn.loadFilter();
		sn.analysis();
		long endtime=System.currentTimeMillis();
		System.out.println("\n处理完成,耗时"+(double)(endtime-starttime)/1000+"秒");
	}

	public void loadFilter(){
		if(cfgPath != null && cfgPath.length() > 0){
			File  filterFile = new File(cfgPath);
			if (filterFile.exists()) {
				String fileName = filterFile.getAbsolutePath();
				BufferedReader in = null;
				try {
					in = new BufferedReader(new InputStreamReader(
							new FileInputStream(fileName)));
					String line = null;
					while ((line = in.readLine()) != null) {
						if(!line.startsWith("BasePath") &&
							!line.startsWith("CustomPath") &&
							!line.startsWith("UpdatePath") &&
							!line.startsWith("JarFile"))
						filter.add(line);
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally{
					if (in != null) {
						try {
							in.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}

		if(cfgLock != null){

		}
	}

	public void loadNegaFilter(String paths){
		if(paths != null)
			for(String path : paths.split(";"))
				negaFilter.add(path);
	}

	public List<String> getFilter(){
		return filter;
	}

	public void setFilter(List<String> paths){
		this.filter = paths;
	}

	public void analysis() {
		System.out.println("======"+SOURCEPATH);
		File file=new File(SOURCEPATH);
		System.out.println("======"+SOURCEPATH);
		List<File> files=null;
		try {
			files=loadFilename(file);
			int filecount=files.size();
			for(int i=0;i<filecount;i++){
				String path=files.get(i).getAbsolutePath();
				createFile(path);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void createFile(String path) throws IOException {
		String dirtree = path.substring(SOURCEPATH.length(),path.lastIndexOf("\\")+1);//目录树
		String p = TARGETPATH;//建立目录树的路径
		String name=path.substring(path.lastIndexOf("\\")+1);//文件名称
		File oldfile=new File(path);
		File dir = new File(p+dirtree);
		if(!dir.exists())
		dir.mkdirs();//创建目录
		copyFile(oldfile,new File(dir, name));
		System.out.println("文件添加成功： "+p+dirtree+name);
	}

	//获取文件夹file目录下所有符合要求的.class和.properties文件
	public  List<File> loadFilename(File file) throws Exception {
	      List<File> filenameList=new ArrayList<File>();
	      if(file.isFile()&&isUseful(file)) {
	          filenameList.add(file);
	      }
	      if(file.isDirectory()&&!".svn".equals(file.getName())&&!isFilterOut(file)) {
	          for(File f:file.listFiles()) {
	        	  if(f.isFile()&&isUseful(f)){
	        		  filenameList.add(f);
	        	  }
	        	  if(f.isDirectory()&&!".svn".equals(f.getName())&&!isFilterOut(f)){
	        		  filenameList.addAll(loadFilename(f));
	        	  }
	          }
	      }
	      return filenameList;
	  }

	private boolean isFilterOut(File file){
		String fileName = file.getAbsolutePath();
		if (fileName.endsWith("\\") || fileName.endsWith("/")) {
			fileName = fileName.substring(0, fileName.length()-1);
		}
//		int len = filter.size();
//		for (int i = 0; i < len; i++) {
//			if(filter.get(i).equals(fileName)){
//				return false;
//			}
//		}
		if(filter.contains(fileName))
			return false;
		return true;
	}

	private boolean isUseful(File file) throws Exception {
		boolean isIgnored = false;
		if(negaFilter.contains(file.getParent()))
			isIgnored = true;
		return !file.getName().endsWith(".scc")&&isModify(file) && !isIgnored;
	}

	//类型为.class或.properties
	private boolean isAvilableType(File file){
		return (file.getName().endsWith("class")||file.getName().endsWith("properties"));
	}

	//判断文件是否增量
	private boolean isModify(File file) throws Exception{
		String p=file.getAbsolutePath().substring(SOURCEPATH.length());
		File f=new File(COMPAREPATH+p);
		if(!f.exists() || isIgnoreUpdate)
			return true;
		return !MD5Util.getFileMD5String(file).equals(MD5Util.getFileMD5String(f));
	}

	public void copyFile(File sourceFile,File targetFile)
		throws IOException{
	        // 新建文件输入流并对它进行缓冲
	        FileInputStream input = new FileInputStream(sourceFile);
	        BufferedInputStream inBuff=new BufferedInputStream(input);

	        // 新建文件输出流并对它进行缓冲
	        FileOutputStream output = new FileOutputStream(targetFile);
	        BufferedOutputStream outBuff=new BufferedOutputStream(output);

	        // 缓冲数组
	        byte[] b = new byte[1024 * 5];
	        int len;
	        while ((len =inBuff.read(b)) != -1) {
	            outBuff.write(b, 0, len);
	        }
	        // 刷新此缓冲的输出流
	        outBuff.flush();

	        //关闭流
	        inBuff.close();
	        outBuff.close();
	        output.close();
	        input.close();
	 }


	public void setSOURCEPATH(String sourcepath) {
		SOURCEPATH = sourcepath;
	}

	public String getSOURCEPATH() {
		return SOURCEPATH;
	}

	public void setCOMPAREPATH(String comparepath) {
		COMPAREPATH = comparepath;
	}

	public void setTARGETPATH(String targetpath) {
		TARGETPATH = targetpath;
	}

	public void setCfgPath(String cfgPath){
		this.cfgPath = cfgPath;
	}

	public void setIgnoreUpdate(boolean isIgnoreUpdate){
		this.isIgnoreUpdate = isIgnoreUpdate;
	}

	public void setCfgLock(FileLock cfgLock){
		this.cfgLock = cfgLock;
	}
}
